package vitaliy.bondar.diamondcave;

import org.andengine.engine.Engine;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.ui.IGameInterface.OnCreateSceneCallback;

public class SceneManager
{
    //---------------------------------------------
    // SCENES
    //---------------------------------------------
    
    private BaseScene splashScene;
    private BaseScene menuScene;
    private BaseScene gameScene;
    private BaseScene loadingScene;
    private BaseScene selectorScene;
    private BaseScene gameOverScene;
    private BaseScene levelCompleteScene;
    private BaseScene optionsScene;
    
    //---------------------------------------------
    // VARIABLES
    //---------------------------------------------
    
    private static final SceneManager INSTANCE = new SceneManager();
    
    private SceneType currentSceneType = SceneType.SCENE_SPLASH;
    
    private BaseScene currentScene;
    private int currentLevel;
    
    private Engine engine = ResourcesManager.getInstance().engine;
    
    public enum SceneType
    {
        SCENE_SPLASH,
        SCENE_MENU,
        SCENE_GAME,
        SCENE_LOADING,
        SCENE_LEVEL_SELECTOR,
        SCENE_GAME_OVER,
        SCENE_LEVEL_COMPLETE,
        SCENE_OPTIONS,
    }
    
    //---------------------------------------------
    // CLASS LOGIC
    //---------------------------------------------
    
    public void setScene(BaseScene scene)
    {
        engine.setScene(scene);
        currentScene = scene;
        currentSceneType = scene.getSceneType();
    }
    
    public void setScene(SceneType sceneType)
    {
        switch (sceneType)
        {
            case SCENE_MENU:
                setScene(menuScene);
                break;
            case SCENE_GAME:
                setScene(gameScene);
                break;
            case SCENE_SPLASH:
                setScene(splashScene);
                break;
            case SCENE_LOADING:
                setScene(loadingScene);
                break;
            case SCENE_LEVEL_SELECTOR:
            	setScene(selectorScene);
            	break;
            case SCENE_GAME_OVER:
            	setScene(gameOverScene);
            	break;
            case SCENE_LEVEL_COMPLETE:
                setScene(levelCompleteScene);
                break;
            case SCENE_OPTIONS:
            	setScene(optionsScene);
            	break;
            default:
                break;
        }
    }
    
    //---------------------------------------------
    // GETTERS AND SETTERS
    //---------------------------------------------
    
    public static SceneManager getInstance()
    {
        return INSTANCE;
    }
    
    public SceneType getCurrentSceneType()
    {
        return currentSceneType;
    }
    
    public BaseScene getCurrentScene()
    {
        return currentScene;
    }
    
    public void createSplashScene( OnCreateSceneCallback pOnCreateSceneCallback )
    {
        ResourcesManager.getInstance().loadSplashScreen();
        splashScene = new SplashScene();
        currentScene = splashScene;
        pOnCreateSceneCallback.onCreateSceneFinished(splashScene);
    }
    
    private void disposeSplashScene()
    {
        ResourcesManager.getInstance().unloadSplashScreen();
        splashScene.disposeScene();
        splashScene = null;
    }
    
    public void createMenuScene()
    {
        ResourcesManager.getInstance().loadMenuResources();
        ResourcesManager.getInstance().loadMenuFonts();
        currentLevel = -1;
        menuScene = new MainMenuScene();
        loadingScene = new LoadingScene();
        SceneManager.getInstance().setScene(menuScene);
        disposeSplashScene();
    }
    
    public void loadGameScene(final Engine mEngine, final int level)
    {
    	final BaseScene prevScene = currentScene;
        setScene(loadingScene);
        prevScene.disposeScene();
        
        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                ResourcesManager.getInstance().loadGameResources();
                GameScene scene = new GameScene();
                scene.loadLevel( level );
                gameScene = scene;
                gameOverScene = new GameOverScene();
                levelCompleteScene = new LevelCompleteScene();
                setScene(gameScene);
            }
        }));
    }
    
    public void loadMenuScene(final Engine mEngine)
    {
    	final BaseScene prevScene = currentScene;
        setScene(loadingScene);
        prevScene.disposeScene();
        
        if (prevScene == optionsScene)
        {
        	loadingScene = null;
        	loadingScene = new LoadingScene();
        }

        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                currentLevel = -1;
                mEngine.unregisterUpdateHandler(pTimerHandler);
                ResourcesManager.getInstance().loadMenuResources();
                menuScene = new MainMenuScene();
                setScene(menuScene);
            }
        }));
    }
    
    public void loadSelectorScene(final Engine mEngine)
    {
    	final BaseScene prevScene = currentScene;
    	setScene(loadingScene);
    	prevScene.disposeScene();
    	
        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                ResourcesManager.getInstance().loadSelectorResources();
                SelectorScene scene = new SelectorScene();
                if (currentLevel != -1 )
                {
                    scene.setCurrentLevel(currentLevel);
                }
                selectorScene = scene;
                setScene(selectorScene);
            }
        }));
    }
    
    public void replay(final Engine mEngine)
    {
    	setScene(loadingScene);
        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                gameScene = null;
                GameScene scene = new GameScene();
                scene.loadLevel( currentLevel );
                gameScene = scene;
                setScene(gameScene);
            }
        }));
    }
    
    public void loadNextLevel(final Engine mEngine)
    {
        setScene(loadingScene);
        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                gameScene = null;
                GameScene scene = new GameScene();
                scene.loadLevel( currentLevel + 1 );
                gameScene = scene;
                setScene(gameScene);
            }
        }));
    }
    
    public void loadOptionsScene(final Engine mEngine)
    {
        final BaseScene prevScene = currentScene;
        setScene(loadingScene);
        prevScene.disposeScene();
    	
        mEngine.registerUpdateHandler(new TimerHandler(0.1f, new ITimerCallback() 
        {
            public void onTimePassed(final TimerHandler pTimerHandler) 
            {
                mEngine.unregisterUpdateHandler(pTimerHandler);
                ResourcesManager.getInstance().loadOptionsResources();
                optionsScene = new OptionsScene();
                setScene(optionsScene);
            }
        }));
    }
    
    
    public void loadGameOverScene(final Engine mEngine)
    {
		setScene(gameOverScene);
    }
    
    public void loadLevelCompleteScene(final Engine mEngine)
    {
        setScene(levelCompleteScene);
    }
    
    public void setCurrentLevel(final int levelNumber)
    {
    	currentLevel = levelNumber;
    }
    
    public void onActivityPaused()
    {
        switch (currentSceneType)
        {
            case SCENE_MENU:
            	ResourcesManager.getInstance().unloadMenuGraphics();
            	ResourcesManager.getInstance().unloadMenuAudio();
                break;
            case SCENE_GAME:
            case SCENE_GAME_OVER:
            case SCENE_LEVEL_COMPLETE:
                ResourcesManager.getInstance().unloadGameGraphics();
                ResourcesManager.getInstance().unloadGameAudio();
                break;
            case SCENE_LEVEL_SELECTOR:
            	ResourcesManager.getInstance().unloadSelectorGraphics();
            	break;
            case SCENE_OPTIONS:
            	ResourcesManager.getInstance().unloadOptionsResources();
            	break;
            default:
                break;
        }
    }
    
    public void onActivityResumed()
    {
    	switch (currentSceneType)
    	{
    	case SCENE_MENU:
    		ResourcesManager.getInstance().loadMenuGraphics();
    		ResourcesManager.getInstance().loadMenuAudio();
    		break;
    	case SCENE_GAME:
    	case SCENE_GAME_OVER:
        case SCENE_LEVEL_COMPLETE:
            ResourcesManager.getInstance().loadGameGraphics();
            ResourcesManager.getInstance().loadGameAudio();
            break;
    	case SCENE_LEVEL_SELECTOR:
    		ResourcesManager.getInstance().loadSelectorGraphics();
    		break;
    	case SCENE_OPTIONS:
    		ResourcesManager.getInstance().loadOptionsResources();
    		break;
    	default:
    		break;
    	}
    }
}
